﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using TimeLineControlNamedPipes.Communication;
using TimeLineDataContract;
using System.Collections.Generic;
using System.Linq;

namespace TimeLineControlPowerPointAddIn
{
    public partial class ThisAddIn
    {

        #region Fields Declaretions

        internal const string CurrentPipeNameOut = "TimeLineControl";
        internal static string CurrentPipeNameIn = "TimeLinePowerPoint";

        internal static Dictionary<string, Dictionary<long, SlideDeskContract>> DicSlides;
        internal static string CurrentAppName = string.Empty;
        internal static TimeLineControlNamedPipes.ReceiverPipe PipeReceiverPipe;
        internal static bool? TimeLineBarVisible;

        private static bool _sendAppName;
        private static Timer _tmSendAppName;
        private static bool _updateRibbonStatusbar;
        private static bool _emptyPres;


        private static DateTime? _lastkeepAlive;
        private static TimeSpan? _difkeepAlive;

        internal static bool SendDeckToTimeLineControl;

        private static bool _runningShowPresentation;
        private static bool _startShowPresentation;
        private static SlideShowSettings _showSettings;
        private static bool _fistConnection;

        #endregion

        #region AddIn Events

        private void ThisAddIn_Startup(object sender, EventArgs e)
        {
            //SLIDES DATA DICTIONARY 
            DicSlides = new Dictionary<string, Dictionary<long, SlideDeskContract>>();

            //PIPE POWEPOINT RECEIVER
            PipeReceiverPipe = new TimeLineControlNamedPipes.ReceiverPipe(CurrentPipeNameIn);
            PipeReceiverPipe.ServiceOn(PipeService.UriPowerPoint);
            PipeReceiverPipe.PipeIsConnected += PipeOkReceiver;
            PipeReceiverPipe.TimeLineShowbar += TimeLineShowbar;
            PipeReceiverPipe.SlidesDeckReady += RequestSlidesDeck;
            PipeReceiverPipe.SlideChange += StartShowSlide;

            //EVENTS POWERPOINT
            Application.SlideSelectionChanged += Application_SlideSelectionChanged;
            Application.PresentationSave += Application_PresentationSave;
            Application.PresentationNewSlide += Application_PresentationNewSlide;
            Application.PresentationOpen += Application_PresentationOpen;
            Application.SlideShowBegin += Application_SlideShowBegin;
            Application.SlideShowEnd += Application_SlideShowEnd;
            Application.SlideShowNextSlide += Application_SlideShowNextSlide;

            //TIMER TO SEND NAME POWERPOINT TO TIMELNE CONTROL
            _tmSendAppName = new Timer { Interval = 300 };
            _tmSendAppName.Tick += TmSendAppName_Tick;
            _tmSendAppName.Start();

        }

        private void ThisAddIn_Shutdown(object sender, EventArgs e)
        {
            _tmSendAppName.Stop();
            if (PipeReceiverPipe != null)
            {
                PipeReceiverPipe.ServiceOff();
            }
            Application.SlideSelectionChanged -= Application_SlideSelectionChanged;
            Application.PresentationSave -= Application_PresentationSave;
            Application.PresentationNewSlide -= Application_PresentationNewSlide;
            Application.PresentationOpen -= Application_PresentationOpen;
            Application.SlideShowBegin -= Application_SlideShowBegin;
            Application.SlideShowEnd -= Application_SlideShowEnd;
            Application.SlideShowNextSlide -= Application_SlideShowNextSlide;
        }

        #endregion

        #region Application PowerPint Events

        private static void Application_SlideShowNextSlide(SlideShowWindow wn)
        {
            _runningShowPresentation = true;
            try
            {
                TimeLineControlNamedPipes.SenderPipe.SendTimeLineCurrentSlide(DicSlides[CurrentAppName][wn.View.Slide.SlideID], CurrentPipeNameOut);
            }
             catch
            {
                var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
                EnabledRibGroupTimeLineControl(false, rib);
            }
         }

        private static void Application_SlideShowEnd(Presentation pres)
        {
            _runningShowPresentation = false;
            try
            {
                TimeLineControlNamedPipes.SenderPipe.SendTimeLineShowSlideRunning(_runningShowPresentation, CurrentPipeNameOut);
            }
           catch
            {
                var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
                EnabledRibGroupTimeLineControl(false, rib);
            }
        }

        private static void Application_SlideShowBegin(SlideShowWindow wn)
        {
            _runningShowPresentation = true;
            try
            {
                TimeLineControlNamedPipes.SenderPipe.SendTimeLineShowSlideRunning(_runningShowPresentation, CurrentPipeNameOut);
            }
            catch
            {
                var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
                EnabledRibGroupTimeLineControl(false, rib);
            }
         }

        private static void Application_PresentationOpen(Presentation pres)
        {
            var tmlcsaved = ReadFileTimeLine(pres.Path, pres.Name);
            var cur = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            CurrentAppName = pres.Name;
            if (!DicSlides.ContainsKey(CurrentAppName))
            {
                DicSlides.Add(CurrentAppName, new Dictionary<long, SlideDeskContract>());
            }
            else
            {
                DicSlides[CurrentAppName].Clear();
            }
            foreach (Slide sldRange in pres.Slides)
            {
                DicSlides[CurrentAppName].Add(sldRange.SlideID,
                    new SlideDeskContract
                    {
                        DockPosition = DockWindows.Top,
                        ElaspTime = new TimeSpan(),
                        FullScreen = true,
                        Id = sldRange.SlideID,
                        Visibled = (sldRange.SlideShowTransition.Hidden == MsoTriState.msoFalse),
                        SlideNumber = sldRange.SlideIndex,
                        Title = "Slide ID " + sldRange.SlideID
                    });
            }
            //update data
            foreach (var savedslides in
                tmlcsaved.Where(savedslides => DicSlides[CurrentAppName].ContainsKey(savedslides.Value.Id)))
            {
                DicSlides[CurrentAppName][savedslides.Value.Id].DockPosition = savedslides.Value.DockPosition;
                DicSlides[CurrentAppName][savedslides.Value.Id].ElaspTime = savedslides.Value.ElaspTime;
                DicSlides[CurrentAppName][savedslides.Value.Id].FullScreen = savedslides.Value.FullScreen;
                DicSlides[CurrentAppName][savedslides.Value.Id].Title = savedslides.Value.Title;
            }
            _emptyPres = false;
            Cursor.Current = cur;
        }

        private void Application_PresentationNewSlide(Slide sld)
        {
            var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
            rib.SuspendLayout();
            rib.LblTotSlides.Label = Application.ActivePresentation.Slides.Count.ToString();
            rib.ResumeLayout(true);
            SendDeckToTimeLineControl = true;
        }

        private void Application_SlideSelectionChanged(SlideRange sldRange)
        {
            _emptyPres = false;
            if (sldRange.Count > 1) return;

            if (sldRange.SlideIndex == 0)
            {
                ShowEmptyRibbonTimeLineControl();
                return;
            }

            var cur = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;

            //update dictionary
            CurrentAppName = Application.ActivePresentation.Name;
            if (!DicSlides.ContainsKey(CurrentAppName))
            {
                DicSlides.Add(CurrentAppName, new Dictionary<long, SlideDeskContract>());
            }
            if (!DicSlides[CurrentAppName].ContainsKey(sldRange.SlideID))
            {
                DicSlides[CurrentAppName].Add(sldRange.SlideID, new SlideDeskContract
                {
                    DockPosition = DockWindows.Top,
                    ElaspTime = new TimeSpan(),
                    FullScreen = true,
                    Id = sldRange.SlideID,
                    Visibled = (sldRange.SlideShowTransition.Hidden == MsoTriState.msoFalse),
                    SlideNumber = sldRange.SlideIndex,
                    Title = "Slide ID " + sldRange.SlideID
                });
                SendDeckToTimeLineControl = true;
            }

            //Slide Delete ?
            if (DicSlides[CurrentAppName].Count > Application.ActivePresentation.Slides.Count)
            {
                ValidadeDicSlides();
                SendDeckToTimeLineControl = true;
            }

            var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
            if (rib.LblSlideID.Label != sldRange.SlideID.ToString())
            {
                if (rib.BntOkTime.Tag == null)
                {
                    rib.BntOkTime.Tag = string.Empty;
                }
                if (rib.BntTitle.Tag == null)
                {
                    rib.BntTitle.Tag = string.Empty;
                }
                if (rib.BntOkTime.Tag.ToString() == "1")
                {
                    var result = MessageBox.Show(string.Format(ResMng.StringResource("MsgQuestSavePending"), ResMng.StringResource("SlideTime")), ResMng.StringResource("NameApp"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                    if (result == DialogResult.Yes)
                    {
                        DicSlides[CurrentAppName][long.Parse(rib.LblSlideID.Label)].ElaspTime = TimeSpan.Parse(rib.editBoxSlideTime.Text);
                        SendDeckToTimeLineControl = true;
                    }
                }
                if (rib.BntTitle.Tag.ToString() == "1")
                {
                    var result = MessageBox.Show(string.Format(ResMng.StringResource("MsgQuestSavePending"), ResMng.StringResource("SlideTitle")), ResMng.StringResource("NameApp"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                    if (result == DialogResult.Yes)
                    {
                        DicSlides[CurrentAppName][long.Parse(rib.LblSlideID.Label)].Title = rib.editBoxSlideTitle.Text;
                        SendDeckToTimeLineControl = true;
                    }
                }
            }
            rib.SuspendLayout();
            rib.LblSlideNumber.Label = string.Format("Slide {0}", DicSlides[CurrentAppName][sldRange.SlideID].SlideNumber);
            rib.LblSlideID.Label = DicSlides[CurrentAppName][sldRange.SlideID].Id.ToString();
            rib.editBoxSlideTime.Text = TimeSpanFormat(DicSlides[CurrentAppName][sldRange.SlideID].ElaspTime);
            rib.editBoxSlideTime.Tag = rib.editBoxSlideTime.Text;
            rib.editBoxSlideTitle.Text = DicSlides[CurrentAppName][sldRange.SlideID].Title;
            rib.editBoxSlideTitle.Tag = rib.editBoxSlideTitle.Text;
            rib.ChkFullScreen.Checked = DicSlides[CurrentAppName][sldRange.SlideID].FullScreen;
            rib.LblTotSlides.Label = CountSlides(Application.ActivePresentation).ToString();
            rib.LblTotTime.Label = TimeSpanFormat(TotalTimePresentation(Application.ActivePresentation));
            rib.BntOkTime.Image = Properties.Resources.icn_troca;
            rib.BntTitle.Image = Properties.Resources.icn_troca;
            rib.BntTitle.Tag = null;
            rib.BntOkTime.Tag = null;
            switch (DicSlides[CurrentAppName][sldRange.SlideID].DockPosition)
            {
                case DockWindows.Top:
                    rib.dropDownPosition.SelectedItemIndex = 0;
                    break;
                case DockWindows.Bottom:
                    rib.dropDownPosition.SelectedItemIndex = 1;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            rib.ResumeLayout(true);
            Cursor.Current = cur;
        }

        private static void Application_PresentationSave(Presentation pres)
        {
            if (CurrentAppName != pres.Name)
            {
                //copy DicSlides to new key and remove old key
                if (!DicSlides.ContainsKey(pres.Name))
                {
                    DicSlides.Add(pres.Name, new Dictionary<long, SlideDeskContract>());
                }
                foreach (var dicSlide in DicSlides[CurrentAppName])
                {
                    DicSlides[pres.Name].Add(dicSlide.Key, dicSlide.Value);
                }
                DicSlides.Remove(CurrentAppName);
            }
            SaveFileTimeLine(pres.Name, pres.Path, pres.Name);
        }

        #endregion

        #region PipeReceiverPipe Events

        internal void PipeOkReceiver()
        {
            //EVENT RECEIVER KEEP ALIVE FROM TIMELINE CONTROL

            if (_lastkeepAlive.HasValue)
            {
                // ReSharper disable PossibleInvalidOperationException
                _difkeepAlive = new TimeSpan(DateTime.Now.Ticks - _lastkeepAlive.Value.Ticks);
                // ReSharper restore PossibleInvalidOperationException
                _lastkeepAlive = DateTime.Now;
            }
            else
            {
                _fistConnection = true;
                try
                {
                    if (Application.ActivePresentation.SlideShowWindow.View.CurrentShowPosition != 0)
                    {
                        _runningShowPresentation = true;
                    }
                }
                // ReSharper disable EmptyGeneralCatchClause
                catch { }
                // ReSharper restore EmptyGeneralCatchClause
                 _lastkeepAlive = DateTime.Now;
                _difkeepAlive = new TimeSpan(0, 0, 60);
            }
            if (_fistConnection && _runningShowPresentation)
            {
                _sendAppName = false;
            }
            else
            {
                _sendAppName = true;
            }

        }

        private void StartShowSlide(SlideDeskContract request)
        {
            var startIndex = request.SlideNumber;
            var endIndex = Application.ActivePresentation.Slides.Count;
            //START SHOW PRESENTATION
            _showSettings = Application.ActivePresentation.SlideShowSettings;
            _showSettings.StartingSlide = startIndex;
            _showSettings.EndingSlide = endIndex;
            _showSettings.RangeType = PpSlideShowRangeType.ppShowAll;
            _showSettings.AdvanceMode = PpSlideShowAdvanceMode.ppSlideShowManualAdvance;
            _showSettings.LoopUntilStopped = MsoTriState.msoFalse;
            _showSettings.ShowType = PpSlideShowType.ppShowTypeSpeaker;
            _startShowPresentation = true;
        }

        private static void RequestSlidesDeck(SlideDeskContract[] request)
        {
            SendDeckToTimeLineControl = true;
        }

        internal static void TimeLineShowbar(bool show)
        {
            TimeLineBarVisible = show;
            _updateRibbonStatusbar = true;
        }

        #endregion

        #region private/internal Methods/functions

        private static void SaveFileTimeLine(string appname, string path, string filename)
        {
            if (!path.EndsWith("\\"))
            {
                path += "\\";
            }
            var savefile = string.Concat(path, filename, ".tmlc");
            Stream stream = File.Open(savefile, FileMode.OpenOrCreate, FileAccess.Write);
            var bformatter = new BinaryFormatter();
            bformatter.Serialize(stream, DicSlides[appname]);
            stream.Close();
        }

        private static Dictionary<long, SlideDeskContract> ReadFileTimeLine(string path, string filename)
        {
            if (!path.EndsWith("\\"))
            {
                path += "\\";
            }
            var savefile = string.Concat(path, filename, ".tmlc");
            if (File.Exists(savefile))
            {
                var stream = File.Open(savefile, FileMode.Open, FileAccess.Read);
                var bformatter = new BinaryFormatter();
                var result = (Dictionary<long, SlideDeskContract>)bformatter.Deserialize(stream);
                stream.Close();
                stream.Dispose();
                return result;
            }
            return new Dictionary<long, SlideDeskContract>();
        }

        internal static void EnabledRibGroupTimeLineControl(bool enabled, RibbonTimeLineControl rib)
        {
            rib.BntSHowTimeBar.Enabled = enabled;
            if (rib.BntEnableTimeLine.Tag.ToString() == "1")
            {
                rib.BntEnableTimeLine.Image = Properties.Resources.LUZVERD0;
                if (_lastkeepAlive.HasValue)
                {
                    // ReSharper disable PossibleInvalidOperationException
                    rib.BntEnableTimeLine.Label = ResMng.StringResource("TimeLineCtrlON") + " " + _lastkeepAlive.Value.ToLongTimeString();
                    // ReSharper restore PossibleInvalidOperationException
                }
                else
                {
                    rib.BntEnableTimeLine.Label = ResMng.StringResource("TimeLineCtrlON");
                }
            }
            if (rib.BntEnableTimeLine.Tag.ToString() == "0")
            {
                rib.BntEnableTimeLine.Image = Properties.Resources.LUZVERM0;
                rib.BntEnableTimeLine.Label = ResMng.StringResource("TimeLineCtrlOFF");
                rib.BntSHowTimeBar.Enabled = false;
            }
        }

        internal static string TimeSpanFormat(TimeSpan tms)
        {
            tms = new TimeSpan(tms.Hours, tms.Minutes, tms.Seconds);
            return tms.ToString("c");
        }

        internal static TimeSpan TotalTimePresentation(Presentation app)
        {
            var totelapstm = new TimeSpan();
            totelapstm = DicSlides[CurrentAppName].Values.Aggregate(totelapstm, (current, tm) => current.Add(tm.ElaspTime));
            return (from Slide slide in app.Slides
                    where slide.SlideShowTransition.Hidden == MsoTriState.msoTrue
                    where DicSlides[CurrentAppName].ContainsKey(slide.SlideID)
                    select slide).Aggregate(totelapstm, (current, slide) => current.Subtract(DicSlides[CurrentAppName][slide.SlideID].ElaspTime));
        }

        private static void ShowEmptyRibbonTimeLineControl()
        {
            var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));
            rib.SuspendLayout();
            rib.LblSlideNumber.Label = string.Empty;
            rib.LblSlideID.Label = string.Empty;
            rib.editBoxSlideTime.Text = @"00:00:00";
            rib.editBoxSlideTime.Tag = @"00:00:00";
            rib.editBoxSlideTitle.Text = string.Empty;
            rib.editBoxSlideTitle.Tag = string.Empty;
            rib.ChkFullScreen.Checked = true;
            rib.LblTotSlides.Label = @"0";
            rib.LblTotTime.Label = @"00:00:00";
            rib.dropDownPosition.SelectedItemIndex = 0;
            rib.BntOkTime.Image = Properties.Resources.icn_troca;
            rib.BntTitle.Image = Properties.Resources.icn_troca;
            rib.BntTitle.Tag = null;
            rib.BntOkTime.Tag = null;
            rib.ResumeLayout(true);
        }

        internal static int CountSlides(Presentation app)
        {
            return (from Slide slide in app.Slides select slide.SlideShowTransition.Hidden).Count(result => result == MsoTriState.msoFalse);
        }

        private void ValidadeDicSlides()
        {
            var app = Application.ActivePresentation;
            var delsld = new List<long>();
            foreach (var dicSlide in DicSlides[app.Name])
            {
                try
                {
                    app.Slides.FindBySlideID((int)dicSlide.Value.Id);
                }
                catch
                {
                    delsld.Add((dicSlide.Value.Id));
                }
            }
            foreach (var sldId in delsld)
            {
                DicSlides[app.Name].Remove(sldId);
            }
        }

        #endregion

        #region Timer / Sender

        private void TmSendAppName_Tick(object sender, EventArgs e)
        {
            if (_startShowPresentation)
            {
                _startShowPresentation = false;
                _showSettings.Run().View.GotoSlide(_showSettings.StartingSlide);
                _runningShowPresentation = true;
                return;
            }

            var rib = (RibbonTimeLineControl)Globals.Ribbons.GetRibbon(typeof(RibbonTimeLineControl));

            if (_fistConnection)
            {
                _fistConnection = false;
                CurrentAppName = Application.ActivePresentation.Name;
                var sendCurrentAppName = CurrentAppName + Convert.ToChar(1) + (string.IsNullOrEmpty(Application.ActivePresentation.Path) ? string.Empty : Application.ActivePresentation.FullName);
                try
                {
                    TimeLineControlNamedPipes.SenderPipe.SendTimeLinechangeNamePowePoint(sendCurrentAppName,
                                                                                            CurrentPipeNameOut);
                }
                catch
                {
                    EnabledRibGroupTimeLineControl(false, rib);
                }
                var result = DicSlides.ContainsKey(CurrentAppName) ?
                    DicSlides[CurrentAppName].Where(s => s.Value.Visibled).Select(slide => slide.Value).OrderBy(s => s.SlideNumber).ToArray() :
                    new SlideDeskContract[] { };
                try
                {
                    TimeLineControlNamedPipes.SenderPipe.SendTimeLineSlidesDesk(result, CurrentPipeNameOut);
                }
                catch
                {
                    EnabledRibGroupTimeLineControl(false, rib);
                }
                if (_runningShowPresentation)
                {
                    try
                    {
                        TimeLineControlNamedPipes.SenderPipe.SendTimeLineShowSlideRunning(_runningShowPresentation, CurrentPipeNameOut);
                    }
                    catch
                    {
                        EnabledRibGroupTimeLineControl(false, rib);
                    }
                    try
                    {
                        TimeLineControlNamedPipes.SenderPipe.SendTimeLineCurrentSlide(DicSlides[CurrentAppName][Application.ActivePresentation.SlideShowWindow.View.CurrentShowPosition - 1], CurrentPipeNameOut);
                    }
                    catch
                    {
                        EnabledRibGroupTimeLineControl(false, rib);
                    }
                }
                return;
            }

            //update slides index and slide visible
            if (!_runningShowPresentation)
            {
                if (Application.Presentations.Count == 0 && !_emptyPres)
                {
                    _emptyPres = true;
                    ShowEmptyRibbonTimeLineControl();
                }
                else
                {
                    _emptyPres = false;
                }
                try
                {
                    CurrentAppName = Application.ActivePresentation.Name;
                    var qtdslides = 0;
                    var tottmslides = new TimeSpan();
                    foreach (Slide slide in Application.ActivePresentation.Slides)
                    {
                        if (DicSlides[CurrentAppName][slide.SlideID].SlideNumber != slide.SlideIndex)
                        {
                            DicSlides[CurrentAppName][slide.SlideID].SlideNumber = slide.SlideIndex;
                            SendDeckToTimeLineControl = true;
                        }
                        if ((slide.SlideShowTransition.Hidden == MsoTriState.msoFalse) != DicSlides[CurrentAppName][slide.SlideID].Visibled)
                        {
                            DicSlides[CurrentAppName][slide.SlideID].Visibled = (slide.SlideShowTransition.Hidden ==
                                                                                                        MsoTriState.msoFalse);
                            SendDeckToTimeLineControl = true;
                        }
                        if (DicSlides[CurrentAppName][slide.SlideID].Visibled)
                        {
                            qtdslides++;
                            tottmslides = tottmslides.Add(DicSlides[CurrentAppName][slide.SlideID].ElaspTime);
                        }
                    }
                    if (TimeSpanFormat(tottmslides) != rib.LblTotTime.Label)
                    {
                        rib.LblTotTime.Label = TimeSpanFormat(tottmslides);
                    }
                    if (qtdslides.ToString() != rib.LblTotSlides.Label)
                    {
                        rib.LblTotSlides.Label = qtdslides.ToString();
                    }
                }
                catch
                {
                    try
                    {
                        CurrentAppName = ResMng.StringResource("MsgNoActPres");
                        var sendCurrentAppName = string.Empty + Convert.ToChar(1) + string.Empty;
                        TimeLineControlNamedPipes.SenderPipe.SendTimeLinechangeNamePowePoint(sendCurrentAppName,
                                                                                             CurrentPipeNameOut);
                    }
                    catch
                    {
                        EnabledRibGroupTimeLineControl(false, rib);
                    }
                    return;
                }
            }

            //SEND APP NAME 
            if (_sendAppName)
            {

                //UPDATE RIBBON
                rib.BntEnableTimeLine.Tag = "1";
                EnabledRibGroupTimeLineControl(true, rib);

                _sendAppName = false;

                if (!_runningShowPresentation)
                {
                    try
                    {
                        CurrentAppName = Application.ActivePresentation.Name;
                        var sendCurrentAppName = CurrentAppName + Convert.ToChar(1) + (string.IsNullOrEmpty(Application.ActivePresentation.Path) ? string.Empty : Application.ActivePresentation.FullName);
                        try
                        {
                            TimeLineControlNamedPipes.SenderPipe.SendTimeLinechangeNamePowePoint(sendCurrentAppName,
                                                                                                    CurrentPipeNameOut);
                        }
                        catch
                        {
                            EnabledRibGroupTimeLineControl(false, rib);
                        }
                    }
                    catch
                    {
                        try
                        {
                            CurrentAppName = ResMng.StringResource("MsgNoActPres");
                            var sendCurrentAppName = string.Empty + Convert.ToChar(1) + string.Empty;
                            TimeLineControlNamedPipes.SenderPipe.SendTimeLinechangeNamePowePoint(sendCurrentAppName,
                                                                                                    CurrentPipeNameOut);
                        }
                        catch
                        {
                            EnabledRibGroupTimeLineControl(false, rib);
                        }
                        return;
                    }
                }
            }

            //SEND SLIDE DESK
            if (SendDeckToTimeLineControl)
            {
                SendDeckToTimeLineControl = false;
                if (!_runningShowPresentation)
                {
                    var result = DicSlides.ContainsKey(CurrentAppName) ?
                        DicSlides[CurrentAppName].Where(s => s.Value.Visibled).Select(slide => slide.Value).OrderBy(s => s.SlideNumber).ToArray() :
                        new SlideDeskContract[] { };
                    try
                    {
                        TimeLineControlNamedPipes.SenderPipe.SendTimeLineSlidesDesk(result, CurrentPipeNameOut);
                    }
                    catch
                    {
                        EnabledRibGroupTimeLineControl(false, rib);
                    }
                }
            }

            if (_updateRibbonStatusbar)
            {
                _updateRibbonStatusbar = false;
                // ReSharper disable PossibleInvalidOperationException
                if (TimeLineBarVisible.Value)
                // ReSharper restore PossibleInvalidOperationException
                {
                    rib.BntSHowTimeBar.Image = Properties.Resources.LUZVERD0;
                    rib.BntSHowTimeBar.Tag = "1";
                    rib.BntSHowTimeBar.Label = ResMng.StringResource("TimeBarON");
                }
                else
                {
                    rib.BntSHowTimeBar.Image = Properties.Resources.LUZVERM0;
                    rib.BntSHowTimeBar.Tag = "0";
                    rib.BntSHowTimeBar.Label = ResMng.StringResource("TimeBarOFF");
                }
                EnabledRibGroupTimeLineControl(true, rib);
            }


            //CHECK TIMEOUT KEEP ALIVE 
            if (_lastkeepAlive.HasValue)
            {
                // ReSharper disable PossibleInvalidOperationException
                var dif = _difkeepAlive.Value.TotalMilliseconds * 1.25;
                if (_lastkeepAlive.Value.AddMilliseconds(dif) < DateTime.Now)
                {
                    rib.BntEnableTimeLine.Tag = "0";
                    EnabledRibGroupTimeLineControl(false, rib);
                    _lastkeepAlive = null;
                    _difkeepAlive = null;
                }
                // ReSharper restore PossibleInvalidOperationException
            }
        }

        #endregion

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            Startup += ThisAddIn_Startup;
            Shutdown += ThisAddIn_Shutdown;
        }

        #endregion

    }
}
